#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <dirent.h>

#define BUFSIZE 512

long int mydu(struct stat *s, char *name)
{
	DIR *dp = NULL;
	struct dirent *entry = NULL;
	long int total_size = 0;
	char child_path[BUFSIZE] = {0};
	struct stat child;

	dp = opendir(name);

	if (S_ISDIR(s->st_mode)) { // 目录类型,递归计算其中文件的大小
		
		while (1) {
			entry = readdir(dp);
			if (NULL == entry) {
				break; // 到头了，跳出
			}
			if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
				continue; // 跳过当前路径和父路径
			}
			// 本目录路径/子文件（目录）名
			memset(child_path, '\0', BUFSIZE);
			snprintf(child_path, BUFSIZE, "%s/%s", name, entry->d_name);
			// 读出此子文件的元数据
			stat(child_path, &child);
			// 累加此子文件的大小
			total_size += mydu(&child, child_path);
		}

		printf("\e[1;33m目录: %-48s 总计大小: %-8ld\e[m\n", name, total_size);
		return total_size;
	}

	printf("\e[1;34m文件: %-48s 占用大小：%-8ld 实际大小：%-8ld\e[m\n", name, s->st_blocks * 512, s->st_size);

	return s->st_blocks * 512;
}

int main(int argc, char *argv[])
{
	DIR *dp = NULL;
	struct dirent *entry = NULL;
	char entrypath[BUFSIZE] = {0};

	struct stat s;
	long int total_size;

	if (argc < 2)
		return 1;

	stat(argv[1], &s);
	total_size = mydu(&s, argv[1]);

	printf("目录总大小：%ld\n", total_size);

	return 0;
}

